import React from 'react';
import {Layout, Modal} from 'antd';
import BaseComponent from "components/Base/BaseComponent";
import Button from "components/Base/Button";
import Toolbar from "components/Base/Toolbar";
import DataTable from "components/Base/DataTable";
import ModalForm from "components/Base/Modal/ModalForm";
import SearchBar from "components/Base/SearchBar/SearchBar";
import './index.less';
import PropTypes from "prop-types";
import $$ from 'utils';
import {putFile} from "utils/ossutils";

const {Content, Footer, Header} = Layout;

export default class extends BaseComponent {

  static propTypes = {
    showToolbar: PropTypes.bool,
    tableColumns: PropTypes.func,
    searchColumns: PropTypes.func,
    detailSearchColumns: PropTypes.array,
    namespace: PropTypes.string,
    pagination: PropTypes.bool,
    selectType: PropTypes.oneOfType([PropTypes.bool, PropTypes.string]),
    init: PropTypes.func,
    disabledAdd: PropTypes.bool,
    showAddDelete: PropTypes.bool,
    align: PropTypes.string,
    showNum: PropTypes.bool,
    searchBarProps: PropTypes.object,
    modalProps: PropTypes.object,
    picKeys: PropTypes.array, // 图片的key
    pageData: PropTypes.object,  // 分页数据 外部传入
  };

  static defaultProps = {
    align: 'center',
    searchType: 'inline',
    searchCols: {span: 8},
  }

  state = {
    record: null,
    visible: false,
    rows: [],
    pageNum: 1,
    pageSize: 10,
    filters: null,
    sorter: null,
  };


  componentDidMount() {

    !!this.props.onRef && this.props.onRef(this);

    !!this.props.init ?
      this.props.init() :
      this.dispatch({
        type: `${this.getNamespace()}/init`,
        payload: {
          notice: this.showMsg,
        },
      });
  }

  /**
   * 新增
   */
  onAdd = () => {

    this.setState({
      record: null,
      visible: true
    });
  };

  /**
   * 修改
   * @param {object} 表单记录
   */
  onUpdate(record) {

    this.setState({
      record,
      visible: true
    });
  };

  /**
   * 删除
   * @param {object | array} 表单记录, 批量删除时为数组
   */
  onDelete = record => {
    if (!record) return;
    if ($$.isArray(record) && !record.length) return;

    const content = `您是否要删除这${
      $$.isArray(record) ? record.length : ''
    }项？`;

    Modal.confirm({
      title: '注意',
      content,
      onOk: () => {
        this.delete($$.isArray(record) ? record : [record]);
      },
    });
  };

  /**
   * 添加或者更新数据
   */
  async addAndModify(value, record) {

    console.log("addAndModify", value);

    const {picKeys, picGroup} = this.props;

    // 图片判断
    if (!!picKeys){
      for (let i = 0; i < picKeys.length; i++) {
        const picKey = picKeys[i];
        const pic = value[picKey];
        if (!!pic && pic.length > 0) {
          const thumbUrls = [];
          const files = [];
          pic.forEach(value =>{
            const {originFileObj, thumbUrl} = value;
            if (!!originFileObj){
              files.push(originFileObj);
            }
            else if (!!thumbUrl){
              thumbUrls.push(thumbUrl);
            }
          });
          let urlPaths = await putFile(files, picGroup);
          urlPaths.push(...thumbUrls);
          console.log(picKey+" 上传图片后的keys", urlPaths);
          value[picKey] = urlPaths.join(",");
        }
      }
    }

    if (!!record) {
      value = record;
    }

    let v = {};
    Object.keys(value).forEach(key => {
      (!!value[key] || value[key]===0 || value[key]==="0") && (v[key] = value[key])
    });

    this.dispatch({
      type: `${this.getNamespace()}/save`,
      payload: {
        value: v,
        notice: this.showMsg,
        success: () => {
          this.getPageInfo(this.state);
          this.setState({
            record: null,
            visible: false
          });
        }
      }
    });
  }

  delete(values) {
    this.dispatch({
      type: `${this.getNamespace()}/delete`,
      payload: {
        values,
        notice: this.showMsg,
        success: () => {
          this.getPageInfo(this.state);
        }
      }
    });
  }

  getTableColumns() {

    if (!!this.props.tableColumns) {
      if ($$.isFunction(this.props.tableColumns))
        return this.props.tableColumns(this);
      else
        return this.props.tableColumns;
    }
  }

  getSearchColumns() {
    if (!!this.props.searchColumns) {
      if ($$.isFunction(this.props.searchColumns))
        return this.props.searchColumns(this);
      else
        return this.props.searchColumns;
    }
  }

  getDetailSearchColumns() {
    return this.props.detailSearchColumns;
  }

  getOtherView() {

  }

  render() {

    let page;
    const {loading, changing} = this.getModel(this.getNamespace());
    const columns = this.getTableColumns();
    const {rows, record, visible} = this.state;
    const {
      pagination, selectType, disabledAdd, pageData,
      showAddDelete, align, showNum, searchBarProps, modalProps, ...otherProp
    } = this.props;

    if (!!pageData){
      page = pageData;
    }else{
      page = this.getModel(this.getNamespace()).page;
    }

    !!align && columns.forEach(column => {
      if (!!column.tableItem)
        column.tableItem.align = align;
    });


    const dataTableProps = {
      loading,
      columns,
      rowKey: 'id',
      showNum: showNum === undefined ? true : showNum,
      selectType: selectType === 'none' ? undefined : selectType,
      dataItems: page,
      pagination: pagination === undefined ? true : pagination,
      isScroll: true,
      bordered: true,
      onSelect: (keys, rows) => {
        this.setState({rows});
      },
      onChange: (data) => {

        console.log("onChange", data);
        const {pageNum, pageSize, sorter} = data;
        const {filters} = this.state;

        let f = {};
        if (!!filters) {
          Object.keys(filters).forEach(key => {
            !!filters[key] && (f[key] = filters[key])
          });
        }

        this.setState({pageNum, pageSize, filters: f, sorter});
        this.getPageInfo({pageNum, pageSize, filters: f, sorter});
      },
      ...otherProp,
    };

    const modalFormProps = {
      loading: changing,
      record,
      visible,
      columns,
      modalOpts: {
        width: 700
      },
      onCancel: () => {
        this.setState({
          record: null,
          visible: false
        });
      },
      // 新增、修改都会进到这个方法中，
      // 可以使用主键或是否有record来区分状态
      onSubmit: value => {
        this.addAndModify(value);
      },
      ref: (form) => {
        this.form = form;
      },
      ...modalProps,
    };

    const searchColumns = this.getSearchColumns();
    const detailSearchColumns = this.getDetailSearchColumns();

    return (
      <Layout className="crud-page">
        <Header>
          {this.props.showToolbar != false &&
          <Toolbar
            appendLeft={(!!showAddDelete || showAddDelete === undefined) &&
            (
              <Button.Group>
                <Button type="primary" icon="plus" disabled={disabledAdd === undefined ? false : disabledAdd}
                        onClick={this.onAdd}>
                  新增
                </Button>
                <Button icon="delete" disabled={!rows || rows.length == 0}
                        onClick={() => this.onDelete(rows)}>
                  删除
                </Button>
              </Button.Group>
            )
            }

            pullDown={!!detailSearchColumns &&
            <SearchBar type="grid" columns={detailSearchColumns} onSearch={this.onSearch}/>}
          >
            {!!searchColumns && <SearchBar type='inline'
                                           columns={searchColumns}
                                           onSearch={this.onSearch}
                                           onRef={(searchBar) => {
                                             this.setState({searchBar});
                                           }}
                                           {...searchBarProps}/>}
          </Toolbar>
          }
        </Header>
        <Content>
          <ModalForm {...modalFormProps} />
          <DataTable {...dataTableProps}/>
          {this.getOtherView()}
        </Content>

      </Layout>
    );
  }

}
